package com.itfreer.file.service.kindeditor;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.itfreer.file.FileSegmentInfo;
import com.itfreer.file.service.IBucketManageService;
import com.itfreer.file.service.IObjectUploadService;

/**
 * 定义标准的web文件上传rest服务接口
 */
@Component(value = "KindeditorUploadService")
@Path("/file/kindeditor")
public class UploadService {

	@Autowired
	private IObjectUploadService objectUpload;

	@Autowired
	private IBucketManageService bucketManage;

	@Autowired(required = false)
	private KindeditorPara uploadPara;

	private KindeditorPara getUploadPara() {
		if (uploadPara == null) {
			uploadPara = new KindeditorPara();
		}
		return uploadPara;
	}

	/**
	 * 文件上传
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	@POST
	@Path("/uploadFile")
	@Produces(javax.ws.rs.core.MediaType.TEXT_HTML)
	public String uploadFile(@QueryParam("dir") String dir, @Context HttpServletRequest request,
			@Context HttpServletResponse response) throws ServletException, IOException {
		// 定义允许上传的文件扩展名
		HashMap<String, String> extMap = new HashMap<String, String>();
		extMap.put("image", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
		extMap.put("file", "doc,docx,xls,xlsx,ppt,pptx,htm,html,txt,zip,rar,gz,bz2");

		if (!extMap.containsKey(dir)) {
			return getError("上传类型错误");
		}

		// 1、创建一个文件上传解析器
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// threshold 极限、临界值，即硬盘缓存 1M
		factory.setSizeThreshold(1024);

		ServletFileUpload upload = new ServletFileUpload(factory);
		// 设置允许上传的最大文件大小（单位MB）
		upload.setSizeMax(getUploadPara().getMaxSize());
		upload.setHeaderEncoding("UTF-8");

		// 2、判断提交上来的数据是否是上传表单的数据
		if (!ServletFileUpload.isMultipartContent(request)) {
			return getError("不能获取上传文件");
		}

		// 3、使用ServletFileUpload解析器解析上传数据，解析结果返回的是一个List<FileItem>集合，每一个FileItem对应一个Form表单的输入项
		try {
			List<FileItem> list = upload.parseRequest(request);
			HashMap<String, Object> map = new HashMap<String, Object>();
			for (FileItem item : list) {
				if (!item.isFormField()) {
					// 文件内容
					map.put("content", item.getInputStream());
					map.put("name", item.getName());
				}
			}

			// 此文件名是前端控件已转换后唯一的名称，非上传文件原名称
			String fileName = map.get("name").toString();
			// 新文件名
			String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
			if (!Arrays.<String>asList(extMap.get(dir).split(",")).contains(fileExt)) {
				return getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dir) + "格式。");
			}

			String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + fileExt;
			InputStream inputStearm = (InputStream) map.get("content");
			ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
			byte[] buff = new byte[1024];
			int rc = 0;
			while ((rc = inputStearm.read(buff, 0, 1024)) > 0) {
				swapStream.write(buff, 0, rc);
			}
			byte[] content = swapStream.toByteArray();

			// 创建存储块
			String bucketName = getUploadPara().getBucketName();
			bucketManage.createBucket(bucketName);

			// 创建存储文件的目录 ，规则为:当前日期/guid/原文件名
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			String ymd = sdf.format(new Date());
			String objectKey = ymd + "/";
			objectUpload.createDir(bucketName, objectKey);
			objectKey += newFileName;

			// 配置文件大小，需和前台同步
			int segmentSize = getUploadPara().getSegmentSize();

			FileSegmentInfo fileSegmentInfo = new FileSegmentInfo();
			fileSegmentInfo.setSegmentContent(content);
			fileSegmentInfo.setSegmentIndex(0);
			fileSegmentInfo.setSegmentSize(segmentSize);
			fileSegmentInfo.setFileLength(segmentSize * 0);

			if (objectUpload.uploadFile(bucketName, objectKey, fileSegmentInfo, null)) {
				String downloadUrl = getUploadPara().getDownloadBaseUrl() + "/file/kindeditor/download?bucket="
						+ bucketName + "&key=" + objectKey;
				return "{\"error\":0, \"url\":\"" + downloadUrl + "\"}";
			} else {
				return getError("上传文件失败。");
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
			return getError(e.getMessage());
		}
	}

	private String getError(String message) {
		return "{\"error\":1, \"message\":\"" + message + "\"}";
	}
}